<?php
class ServiceUserIdentity extends UserIdentity {
    const ERROR_NOT_AUTHENTICATED = 3;

    /**
     * @var EAuthServiceBase the authorization service instance.
     */
    protected $service;

    /**
     * Constructor.
     * @param EAuthServiceBase $service the authorization service instance.
     */
    public function __construct($service)
    {
        $this->service = $service;
    }

    /**
     * @var User
     */
    protected $_user;

    /**
     * Authenticates a user based on {@link username}.
     * This method is required by {@link IUserIdentity}.
     * @return boolean whether authentication succeeds.
     */
    public function authenticate()
    {
        if ($this->service->isAuthenticated) {
            $this->username = $this->service->getAttribute('name');
            $this->setState('id', $this->service->id);
            $this->setState('name', $this->username);
            $this->setState('service', $this->service->serviceName);

            $record = User::model()->findByAttributes(array(
                                                           'service'  => $this->service->serviceName,
                                                           'identity' => $this->service->id,
                                                      ));

            if (!$record) {
                $model = new User();
                $model->identity = $this->service->id;
                $model->service = $this->service->serviceName;
                $model->name = $this->username;

                if ($model->validate()) {
                    $model->save();
                }

                $this->setState('model', $model);
            } else {
                $this->setState('model', $record);
            }

            $this->errorCode = self::ERROR_NONE;


        } else {
            $this->errorCode = self::ERROR_NOT_AUTHENTICATED;
        }

        return !$this->errorCode;
    }

    /**
     * @return User
     */
    protected function getUser()
    {
        if ($this->_user) {
            return $this->_user;
        }

        return $this->_user = User::model()->findByAttributes(array(
                                                                   'service'  => $this->service->serviceName,
                                                                   'identity' => $this->service->id,
                                                              ));
    }
}